home *** CD-ROM | disk | FTP | other *** search
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: README Makefile debug.c disp.c go.c go.h
- # Wrapped by jdr@hebe.weh.andrew.cmu.edu on Wed Dec 12 14:49:51 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f README -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"README\"
- else
- echo shar: Extracting \"README\" \(846 characters\)
- sed "s/^X//" >README <<'END_OF_README'
- X
- XThe four files included with the current README comprise the go skeleton
- Xprogram written by Jeff Rosenfeld at Carnegie Mellon University in
- XSeptember of 1988. It is hereby placed in the public domain.
- X
- XThe code includes some termcap/curses dependencies that would be trivial
- Xto remove were anyone so inclined. It should build and run easily on any
- Xsystem that supports curses.
- X
- XThe commands are single-characters, as follows:
- X
- X h,j,k,l: move the cursor left, down, up, or right, respectively.
- X y,u,b,n: move the cursor NW, NE, SW, SE, respectively.
- X s: set SKIP mode.
- X p: pass your turn and turn off SKIP mode.
- X .: enter your move at the current cursor location.
- X ^L: redraw the board.
- X (space): continues after a debug message.
- X
- XSKIP mode allows you to set multiple stones down in the current color.
- X
- XEnjoy,
- X - Jeff,
- X (jdr@andrew.cmu.edu).
- END_OF_README
- if test 846 -ne `wc -c <README`; then
- echo shar: \"README\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(93 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- XCFLAGS = -g -O
- X
- XOBJS = go.o disp.o debug.o
- X
- Xgo: $(OBJS)
- X cc -o go $(OBJS) -lcurses -ltermcap
- END_OF_Makefile
- if test 93 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f debug.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"debug.c\"
- else
- echo shar: Extracting \"debug.c\" \(753 characters\)
- sed "s/^X//" >debug.c <<'END_OF_debug.c'
- X#include <curses.h>
- X#include "go.h"
- X
- X/* highlight a group on the board and display a message
- X concerning that group until the space bar is pressed */
- Xshow(pgrp,str)
- X struct group *pgrp;
- X char *str;
- X{
- X register struct elem *spot;
- X int x,y;
- X getyx(stdscr,y,x);
- X standout();
- X mvaddstr(1,15,str);
- X standend();
- X for (spot=pgrp->head; spot; spot=spot->next) spot->color |= 0x80;
- X draw();
- X while (getch() != ' ') beep();
- X for (spot=pgrp->head; spot; spot=spot->next) spot->color &= 0x7F;
- X move(1,15);
- X clrtoeol();
- X move(y,x);
- X draw();
- X}
- X
- X/* display a message near the bottom of the screen */
- Xcomment(fmt,a,b,c,d,e,f)
- X char *fmt;
- X int a,b,c,d,e,f;
- X{
- X int x,y;
- X getyx(stdscr,y,x);
- X move(23,15);
- X printw(fmt,a,b,c,d,e,f);
- X clrtoeol();
- X move(y,x);
- X refresh();
- X}
- END_OF_debug.c
- if test 753 -ne `wc -c <debug.c`; then
- echo shar: \"debug.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f disp.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"disp.c\"
- else
- echo shar: Extracting \"disp.c\" \(2159 characters\)
- sed "s/^X//" >disp.c <<'END_OF_disp.c'
- X#include <curses.h>
- X#include "go.h"
- X
- X/* initialize the curses package and display mode */
- Xsetup()
- X{
- X initscr();
- X crmode();
- X noecho();
- X move(3,7);
- X}
- X
- X/* draws the current game board
- X the debug package might set the high bit on some stones to indicate
- X that those spots should be highlighted */
- Xdraw()
- X{
- X register int i,j;
- X int x,y;
- X getyx(stdscr,y,x);
- X mvaddstr(2,5,"|---------------------------------------|");
- X for (i=0; i<19; ++i) {
- X mvaddch(3+i,5,'|');
- X for (j=0; j<19; ++j) {
- X addch(' ');
- X if (Board[j][i].color & 0x80) standout();
- X switch(Board[j][i].color & 0x7F) {
- X case NONE: addch('+'); break;
- X case BLACK: addch('@'); break;
- X case WHITE: addch('O'); break;
- X default: addch('!'); break; /* ERROR! */
- X }
- X if ((Board[j][i].color & 0x80) &&
- X j+1<19 && !(Board[j+1][i].color & 0x80)) standend();
- X }
- X addch(' '); addch('|');
- X }
- X mvaddstr(3+i,5,"|---------------------------------------|");
- X move(y,x);
- X refresh();
- X}
- X
- X/* relative cursor motion on a flat board with bounds-checking */
- Xrup(dy,dx)
- X int dy,dx;
- X{
- X int x,y;
- X getyx(stdscr,y,x);
- X x += dx; y += dy;
- X if (x < 7 || x >= 45) x -= dx;
- X if (y < 3 || y >= 22) y -= dy;
- X move(y,x);
- X refresh();
- X}
- X
- Xfetchmove(ploc)
- X struct location *ploc;
- X{
- X static int setmode = 0;
- X int done = 0;
- X while (!done) switch (getch()) {
- X case 'j': rup(1,0); break;
- X case 'k': rup(-1,0); break;
- X case 'h': rup(0,-2); break;
- X case 'l': rup(0,2); break;
- X case 'y': rup(-1,-2); break;
- X case 'u': rup(-1,2); break;
- X case 'b': rup(1,-2); break;
- X case 'n': rup(1,2); break;
- X case 's': setmode=1; break;
- X case 'p': setmode=0; return PASS;
- X case 'L'&0x1F: draw(); break;
- X case '.': done=1; break;
- X default: beep(); break;
- X }
- X getyx(stdscr,ploc->y,ploc->x);
- X ploc->x -= 7; ploc->y -= 3;
- X ploc->x /= 2;
- X return setmode?SKIP:MOVE;
- X}
- X
- Xbeep()
- X{
- X static int inited = 0;
- X static char *str = NULL;
- X if (!inited) {
- X str = getcap("bl");
- X if (str == NULL) str = getcap("vb");
- X if (str == NULL) str = "";
- X inited = 1;
- X }
- X write(2,str,strlen(str));
- X}
- X
- X/* the opposite of setup() */
- Xcleanup()
- X{
- X move(23,0);
- X refresh();
- X endwin();
- X}
- END_OF_disp.c
- if test 2159 -ne `wc -c <disp.c`; then
- echo shar: \"disp.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f go.c -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"go.c\"
- else
- echo shar: Extracting \"go.c\" \(5069 characters\)
- sed "s/^X//" >go.c <<'END_OF_go.c'
- X#include <sys/signal.h>
- X#include "go.h"
- X
- X/* offsets for pointer arithmetic in a 19x19 2-space;
- X the first four correspond to N,S,W,E, next are the diagonals, and last is
- X the no-movement offset - this facilitates restricting motion to the
- X taxicab directions without using two arrays */
- Xint Dir[9] = { -19,19,-1,1, -20,-18,18,20, 0 };
- X
- Xstruct elem Board[19][19];
- Xstruct group Groups[50]; /* static limit of 50 groups - ick! */
- X
- X/* there is only ever one spot on the board that cannot be played despite
- X that it will have liberties after the play - this marks that spot */
- Xstruct elem *KoSpot;
- X
- X/* number of consecutive passes */
- Xint Pass;
- X
- X/* bounds-checking */
- X#define onboard(a) ((a) >= &Board[0][0] && (a) <= &Board[19][19])
- X
- X/* runs code for each taxicab direction about the center */
- X#define LOOPAROUND(center,ptr,code) \
- X { register int _i; \
- X for (ptr=(center)+Dir[_i=0]; _i<4; ptr=(center)+Dir[++_i]) \
- X if (onboard(ptr) && adjacent(ptr,(center))) \
- X { code } }
- X
- Xsigexit()
- X{
- X cleanup();
- X exit(1);
- X}
- X
- Xmain()
- X{
- X register int i,j;
- X for (j=0; j<19; ++j) for (i=0; i<19; ++i) {
- X Board[i][j].loc.x = i;
- X Board[i][j].loc.y = j;
- X }
- X setup();
- X signal(SIGINT,sigexit);
- X draw();
- X Pass = 0;
- X do {
- X doturn(BLACK);
- X doturn(WHITE);
- X } while(Pass != 2);
- X cleanup();
- X}
- X
- Xdoturn(whose)
- Xcolor_t whose;
- X{
- X struct location loc;
- X while (1) {
- X comment("%s's turn.",whose==BLACK?"BLACK":"WHITE");
- X switch (fetchmove(&loc)) {
- X case PASS:
- X ++Pass;
- X return;
- X case MOVE:
- X if (checkmove(whose,&loc)) { beep(); continue; }
- X domove(whose,&loc);
- X break;
- X case SKIP:
- X domove(whose,&loc);
- X continue;
- X }
- X break;
- X }
- X Pass = 0; /* if move was not PASS, reset Pass */
- X draw();
- X}
- X
- X/* check the validity of a move - 0 indicates validity, 1 does not.
- X the kospot may be occupied only when a snapback occurs - this is
- X when one of the opponent's groups touching the kospot has only
- X one liberty and more than one element */
- Xcheckmove(turn,loc)
- Xcolor_t turn;
- Xregister struct location *loc;
- X{
- X register int i;
- X struct elem *targ;
- X struct elem *spot = &Board[loc->x][loc->y];
- X if (spot->color != EMPTY) return 1;
- X if (spot == KoSpot) {
- X LOOPAROUND(spot,targ, /* check for snapback */
- X if (targ->color != turn &&
- X targ->group->liberties == 1 &
- X targ->group->head->next != NULL)
- X return 0; /* snapback! */
- X );
- X return 1; /* catch `ko's */
- X }
- X return 0;
- X}
- X
- X/* perform a valid move.
- X this includes updating the group list, possibly joining two or more
- X groups together or creating a new group. we also update liberty counts,
- X killing groups with zero liberties. */
- Xdomove(turn,loc)
- X color_t turn;
- X register struct location *loc;
- X{
- X register int i;
- X int tmp;
- X struct elem *targ;
- X struct elem *spot = &Board[loc->x][loc->y];
- X KoSpot = NULL;
- X mkgroup(spot);
- X spot->group->owner = spot->color = turn;
- X LOOPAROUND(spot,targ,
- X if (targ->color == turn) {
- X if (spot->group != targ->group)
- X nattach(targ->group,spot->group);
- X }
- X else if (targ->color != EMPTY) {
- X tmp = countlibs(targ->group);
- X if (tmp == 0) kill(targ->group);
- X else targ->group->liberties = tmp;
- X }
- X );
- X if ((spot->group->liberties = countlibs(spot->group)) == 0) {
- X kill(spot->group);
- X KoSpot = NULL;
- X }
- X return 0;
- X}
- X
- Xmkgroup(spot)
- Xstruct elem *spot;
- X{
- X register struct group *pgrp;
- X for (pgrp = &Groups[0]; pgrp < &Groups[50]; ++pgrp)
- X if (pgrp->head == NULL) {
- X pgrp->head = spot;
- X pgrp->owner = spot->color;
- X pgrp->flags = 0;
- X spot->group = pgrp;
- X spot->next = NULL;
- X return 0;
- X }
- X return 1;
- X}
- X
- Xkill(grp)
- Xstruct group *grp;
- X{
- X register struct elem *spot;
- X show(grp,"killing");
- X if (grp->head->next == NULL) KoSpot = grp->head;
- X for (spot=grp->head; spot; spot=spot->next)
- X spot->color = EMPTY;
- X grp->head = NULL;
- X}
- X
- X/* attach two groups together without counting liberties */
- Xnattach(dst,grp)
- Xstruct group *dst, *grp;
- X{
- X register struct elem *spot, *tmp;
- X show(grp,"attaching this...");
- X show(dst,"...to this.");
- X for (spot=grp->head; spot; tmp=spot,spot=spot->next)
- X spot->group = dst;
- X tmp->next = dst->head;
- X dst->head = grp->head;
- X grp->head = NULL;
- X return 0;
- X}
- X
- X/* attach two groups, returning the number of liberties in the
- X resulting group */
- Xattach(dst,grp)
- Xstruct group *dst, *grp;
- X{
- X nattach(dst,grp);
- X return (dst->liberties = countlibs(dst));
- X}
- X
- Xcountlibs(grp)
- Xstruct group *grp;
- X{
- X register struct elem *elem, *spot;
- X int count = 0;
- X show(grp,"counting liberties");
- X for (elem=grp->head; elem; elem=elem->next)
- X LOOPAROUND(elem,spot,
- X if (!spot->mark) {
- X spot->mark = 1;
- X if (spot->color == EMPTY)
- X ++count;
- X }
- X );
- X for (elem=grp->head; elem; elem=elem->next)
- X LOOPAROUND(elem,spot,
- X spot->mark = 0;
- X );
- X comment("counted %d liberties",count);
- X return count;
- X}
- END_OF_go.c
- if test 5069 -ne `wc -c <go.c`; then
- echo shar: \"go.c\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f go.h -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"go.h\"
- else
- echo shar: Extracting \"go.h\" \(1523 characters\)
- sed "s/^X//" >go.h <<'END_OF_go.h'
- Xtypedef unsigned short color_t;
- Xtypedef unsigned long bits_t;
- X
- Xstruct location {
- X char x,y; /* assumes chars are SIGNED */
- X};
- X
- X#define EMPTY 0
- X#define NONE EMPTY
- X#define BLACK 1
- X#define WHITE 2
- X
- Xstruct elem {
- X struct elem *next; /* ptr to next stone in group */
- X struct group *group; /* ptr to group descriptor */
- X int mark; /* temp. marker - must always be reset to 0 */
- X struct location loc; /* coordinates of this stone */
- X color_t color; /* color of this stone */
- X};
- X
- Xstruct group {
- X struct elem *head; /* some stone in the group */
- X color_t owner; /* head->color */
- X short liberties; /* how many liberties this group has */
- X bits_t flags; /* group-specific flags */
- X};
- X
- X#define GR_EYE 0x01 /* group has at least one eye */
- X#define GR_LIVE 0x02 /* group is alive */
- X
- X#define setf(bit,place) (place |= (bit))
- X#define clrf(bit,place) (place &= ~(bit))
- X#define getf(bit,place) ((place) & (bit))
- X
- X#define abs(a) ((a)>0 ? (a) : -(a))
- X#define adjacent(a,b) ((abs((a)->loc.x - (b)->loc.x) + \
- X abs((a)->loc.y - (b)->loc.y)) == 1)
- X
- X#define PASS 0 /* player passes */
- X#define MOVE 1 /* player attempts to make a move */
- X#define SKIP 2 /* player enters setup mode */
- X
- X#define UP 0
- X#define DOWN 1
- X#define LEFT 2
- X#define RIGHT 3
- X#define UPLEFT 4
- X#define UPRIGHT 5
- X#define DNLEFT 6
- X#define DNRIGHT 7
- X
- X#ifndef NULL
- X#define NULL 0
- X#endif
- X
- Xextern struct elem Board[19][19]; /* the game board */
- Xextern int Dir[]; /* offsets for relative motion on the board */
- END_OF_go.h
- if test 1523 -ne `wc -c <go.h`; then
- echo shar: \"go.h\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 1 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-
-
-